<?php
/**
 * Created by PhpStorm.
 * User: 000
 * Date: 2024/10/20
 * Time: 13:38
 */

namespace App\Constant;
use AlibabaCloud\Tea\Model;
use App\Models\PaymentLog;
use App\Models\PayRefundLog;
use \Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Http\Request;
use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Config;
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
class AliPay
{

    private static function pay($data){
        //1. 设置参数（全局只需设置一次）
        Factory::setOptions(self::getOptions());
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
//            $result = Factory::payment()->common()->create($data['subject'], $data['sn'], $data['pay_price'], $data['user_id'],$data['order_type']);
            $result = Factory::payment()->wap()->pay("中华龙储值支付", $data['sn'], $data['pay_price'],"http://wallet.hanlinmo.top/#/cancalpayapply"," http://wallet.hanlinmo.top/#/payapply");
            $responseChecker = new ResponseChecker();
            $p_log = new PaymentLog();
            $p_log->name = $data['sn'];
            $p_log->account = $data['sn'];
            $p_log->money = $data['pay_price'];
            $p_log->state = 1;
            $p_log->pay_type = 1;
            $p_log->logs = json_encode($result);
            $p_log->save();
            //3. 处理响应或异常
            if ($responseChecker->success($result)) {
                return  $result->body;
                echo "调用成功". PHP_EOL;
            } else {
                echo "调用失败，原因：". $result->msg."，".$result->subMsg.PHP_EOL;
            }
        } catch (Exception $e) {
            echo "调用失败，". $e->getMessage(). PHP_EOL;;
        }
    }



    /***
     * @return Config
     * 封装参数
     */
    private static function getOptions()
    {
        $options = new Config();
        $options->protocol = 'https';
        $options->gatewayHost = 'openapi.alipay.com';
        $options->signType = 'RSA2';
        $options->appId = getenv('ALY_APPID');//'<-- 请填写您的AppId，例如：2019022663440152 -->';
        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        $options->merchantPrivateKey = getenv('merchantPrivateKey');//'<-- 请填写您的应用私钥，例如：MIIEvQIBADANB ... ... -->';
        $options->alipayCertPath = getenv('alipayCertPath');// '<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->';
        $options->alipayRootCertPath = getenv('alipayRootCertPath');// '<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt" -->';
        $options->merchantCertPath = getenv('merchantCertPath');// '<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->';
        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
//        $options->alipayPublicKey = config('omnipay.options.public_key');//'<-- 请填写您的支付宝公钥，例如：MIIBIjANBg... -->';
        //可设置异步通知接收服务地址（可选）
        $options->notifyUrl = getenv('ALY_NOTIFY');//"<-- 请填写您的支付类接口异步通知接收服务地址，例如：https://www.test.com/callback -->";
        return $options;
    }

    /***
     * @throws \Exception
     * 退款
     */
    private static function baseReturn($data)
    {
        Factory::setOptions(self::getOptions());
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
            //这里使用三段 表示 具体看手册 https://opendocs.alipay.com/open/54/103419/
            $result = Factory::payment()->common()
                ->optional("out_request_no",$data['back_sn']) //out_request_no 是退款的商户自定义编号 不能重复 重复的话会导致后一次的失败
                ->refund($data['sn'], $data['money']); // refund的是退款的方法 还有其他方法可以参见手册  第一个参数为支付时的商户自定义订单号 第二个参数为需要退款的金额
            //这里查看 手册 https://github.com/alipay/alipay-easysdk/blob/master/APIDoc.md
            $responseChecker = new ResponseChecker();
            //3. 处理响应或异常
            if ($w = $responseChecker->success($result)) {
//                $str = substr($data['sn'],0,2);
//                if($str == 'st'){
//                    $order = (new \Illuminate\Database\Eloquent\Model())->where([['sn','=',$data['sn']]])->first();
//                    $order->order_type = 6;
//                }else{
//                    $order = (new Order())->where([['sn','=',$data['sn']]])->first();
//                }
//                $backs["trade_no"] = $result->tradeNo;
//                $backs["out_trade_no"] = $result->outTradeNo;
//                $backs["total_amount"] = $data['money'];
//                PayRefundLog::addAliPayRefundLog($backs,$order,2,1);
                echo 'success';
                return "success";
//                return 'success';
//                return $w;
                //dump($w);
                //处理其他内容
                return $result->body;
                echo "调用成功" . PHP_EOL;
            } else {
                echo "调用失败，原因：" . $result->msg . "，" . $result->subMsg . PHP_EOL;
                return $result->subMsg;
            }
        } catch (Exception $e) {
            echo "调用失败，" . $e->getMessage() . PHP_EOL;;
        }
        // $this->ok(200, '成功', ['data' => $res]);
    }



    /**
     * @param $data
     * @throws \Exception
     * 支付宝提现
     */
    private static function paymentTransfer($data)
    {
        Factory::setOptions(self::getOptions());
        $param = [
            'out_biz_no' => self::getSnNum(),
            'trans_amount' => $data['money'],
            'biz_scene' => "DIRECT_TRANSFER",
            'product_code' => "TRANS_ACCOUNT_NO_PWD",
            'order_title' => "支付宝提现",
            'payee_info' => [
                "identity" => $data['alipay_account'],
                "identity_type" => "ALIPAY_LOGON_ID",
                "name" => $data['alipay_name'],
            ]
        ];
//        $bizParams = json_encode($param);
//        $result = Factory::util()->generic()->sdkExecute("alipay.fund.trans.uni.transfer", [], $param);
        $result = Factory::util()->generic()->execute("alipay.fund.trans.uni.transfer", null, $param);
        $p_log = new PaymentLog();
        $p_log->name = $data['alipay_name'];
        $p_log->account = $data['alipay_account'];
        $p_log->money = $data['money'];
        $p_log->state = 2;
        $p_log->pay_type = 1;
        $p_log->logs = json_encode($result);
        $p_log->save();
        if ($result->code == 10000) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return string
     *
     * 生成订单号
     */
    public static function getSnNum()
    {
        return date('YmdHis') . mt_rand(1000, 9999);
    }

    /**
     * @param Request $request
     * @throws \Exception
     * 提现
     */
    public static function withdrawal($data)
    {
        if(!$data['money'] || ($data['money'] < 0.1) || !$data['alipay_name'] || !$data['alipay_account']){
            return 2;
        }
        $res = self::paymentTransfer($data);
        if ($res) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * @param $data
     * @return bool
     * @throws Exception
     * 退款
     */
    public static function doReturn($data)
    {
        $res = self::baseReturn($data);
        if ($res == 'success') {
            return  true;
        } else {
            return false;
        }
    }


    /**
     * @param $data
     * 开始支付
     */
    public static function payStart($data)
    {
        $res = self::pay($data);
        if (is_string($res)) {
            return $res;
        } else {
            return false;
        }
    }

}